package bakudo.utils.performance.animationRecorder {
	import bakudo.utils.performance.animationRecorder.global.EncodingDecoding;
	import bakudo.utils.performance.animationRecorder.vo.AnimationVO;

	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.net.SharedObject;

	/**
	 * @author Micha� Rabi�ski
	 */
	public class AnimationRecorder {

		/**
		 * Object beeing recorded
		 */
		private var subject : DisplayObject;

		/**
		 * Stage framerate
		 */
		private var frameRate : uint;

		/**
		 * Amount of frames of subject's parent
		 */
		private var totalFrames : uint;

		/**
		 * In this array we store animationVO objects 
		 * containing all usefull data
		 */
		private var animationData : Array/*of AnimationVO*/;

		/**
		 * When we save animation data we use SharedObject to save it locally 
		 */
		private var sharedData : SharedObject;

		/**
		 * When true, we start to write animation's data
		 */
		private var recordingIsOn : Boolean;

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PUBLIC METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		public function setLock(subjectToLock : DisplayObject,parentOfSubject : MovieClip) : void {
			subject = subjectToLock;
			totalFrames = parentOfSubject.totalFrames;
			frameRate = parentOfSubject.stage.frameRate;
			recordingIsOn = false;
			animationData = [];
			parentOfSubject.addEventListener(Event.ENTER_FRAME, onSubjectEnterFrame);
		}

		public function startRecording() : void {
			trace('recording started');
			recordingIsOn = true;
		}

		public function stopRecording() : void {
			trace('recording stopped');
			recordingIsOn = false;
		}

		public function traceAnimationData() : void {
			var vo : AnimationVO;
			for(var i in animationData) {
				vo = animationData[i] as AnimationVO;
				trace(vo.x);				trace(vo.y);				trace(vo.scaleX);				trace(vo.scaleY);				trace(vo.rotation);
				for(var j in vo) {
					trace((vo[j]), j);
				}
			}
		}

		public function saveData(setName : String) : void {
			var temp : String = getEncodedData();
			sharedData = SharedObject.getLocal(setName);
			sharedData.data["animationData"] = temp;
			sharedData.flush();
		}

		public function loadData(setName : String) : void {
			sharedData = SharedObject.getLocal(setName);
			var data : String /*of String*/ = sharedData.data["animationData"];
			getDecodedData(data);
			traceAnimationData();
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PRIVATE METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		private function writeAnimationData() : void {
			trace('write');
			var animationVO : AnimationVO = new AnimationVO();
			animationVO.x = subject.x;			animationVO.y = subject.y;			animationVO.rotation = subject.rotation;			animationVO.scaleX = subject.scaleX;			animationVO.scaleY = subject.scaleY;
			animationData.push(animationVO);
		}

		private function getEncodedData() : String {
			var data : String = '';
			var vo : AnimationVO;
			for(var i in animationData) {
				vo = animationData[i];
				data += vo.x + EncodingDecoding.FIELD_DELIMITER;				data += vo.y + EncodingDecoding.FIELD_DELIMITER;				data += vo.scaleX + EncodingDecoding.FIELD_DELIMITER;				data += vo.scaleY + EncodingDecoding.FIELD_DELIMITER;				data += vo.rotation;
				if(i != animationData.length - 1) data += EncodingDecoding.ITEM_DELIMITER;
			}
			return data;
		}

		private function getDecodedData(data : String) : void {
			var items : Array /*of String*/;
			var fields : Array/*of Number*/;
			var vo : AnimationVO;
			animationData = [];
			items = data.split(EncodingDecoding.ITEM_DELIMITER);
			for(var i in items) {
				fields = (items[i] as String).split(EncodingDecoding.FIELD_DELIMITER);
				vo = new AnimationVO();
				vo.x = fields[0];				vo.y = fields[1];				vo.scaleX = fields[2];				vo.scaleY = fields[3];				vo.rotation = fields[4];
				animationData.push(vo);
			}
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PRIVATE LISTENERS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		private function onSubjectEnterFrame(e : Event) : void {
			if(recordingIsOn)writeAnimationData();
		}
	}
}
